--[[
	GMod Last Man Standing, a gamemode for Garry's Mod
    Copyright (C) 2012 Wickex

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
]]

AddCSLuaFile("cl_init.lua")
AddCSLuaFile("shared.lua")
AddCSLuaFile("player_ext_shd.lua")
AddCSLuaFile("cl_hud.lua")

include("shared.lua")
include("player.lua")
include("player_ext_shd.lua")

CreateConVar("glms_gracetime", "10", FCVAR_NOTIFY)
CreateConVar("glms_initialgracetime", "60", FCVAR_NOTIFY)
CreateConVar("glms_roundtime", "10", FCVAR_NOTIFY)
CreateConVar("glms_additionaltime", "2", FCVAR_NOTIFY)
CreateConVar("glms_endtime", "10", FCVAR_NOTIFY)
CreateConVar("glms_debug", "0", FCVAR_NOTIFY)

local glms_minply = CreateConVar("glms_minimum_players", "2", FCVAR_ARCHIVE + FCVAR_NOTIFY)

function GM:Initialize()
	MsgN("GLMS initializing...")
	
	--Friendly fire should be on
	RunConsoleCommand("mp_friendlyfire", "1")
	
	GAMEMODE.round = ROUND_WAIT --Setting the round state
	GAMEMODE.FirstRound = true --Mark as first round so there's an extended ROUND_GRACE
	
	SetGlobalFloat("glms_round_end", -1)
	
	game.ConsoleCommand("say Initializing\n")
	--WaitForPlayers()
	
	timer.Simple(2, MsgN("Lol"))
	timer.Simple(3, GraceRound())
end

function RoundUmsg(round, ply)
	if ply then
		umsg.Start("round", ply)
	else
		umsg.Start("round")
	end
	umsg.Char(round)
	umsg.End()
end

function SetRound(round)
	GAMEMODE.round = round
	RoundUmsg(round)
end

function GetRound()
	return GAMEMODE.round
end

local function EnoughPlayers()
	local ready = 0
	for _, ply in pairs(player.GetAll()) do
		if IsValid(ply) then
			ready = ready + 1
		end
	end
	return ready >= glms_minply:GetInt()
end

function WaitingForPlayersChecker()
	if GetRound() == ROUND_WAIT then
		if EnoughPlayers() then
			timer.Create("waitgraceround", 1, 1, GraceRound)
			timer.Stop("waitingforply")
		end
	end
end

function WaitForPlayers()
	local debug = GetConVar("glms_debug"):GetInt()
	if debug == 1 then
		GraceRound()
		return
	end
	SetRound(ROUND_WAIT)

	if not timer.Start("waitingforply") then
		timer.Create("waitingforply", 2, 0, WaitingForPlayersChecker)
	end
end

function CheckForWin()
	local alivecount = 0
	for k,v in pairs(player.GetAll()) do
		if v:Alive() and v:IsSurvivalist() then
			local alivecount = alivecount + 1
			winner = v:SteamID() --Only gets called when there's 1 person to be counted
		end
	end
	
	if alivecount > 2 then
		return ALIVE
	elseif alivecount == 2 then
		return TWO
	elseif alivecount == 1 then
		return WIN
	elseif alivecount < 1 then
		return TIE
	end	
	
	return ALIVE
end

local function WinCheck()
	if GetRound() == ROUND_START then
		if CurTime() > GetGlobalFloat("glms_round_end", 0) then
			FinalRound()
		else
			local status = CheckForWin()
			if status == ALIVE then return
			elseif status == WIN then
				EndRound(status)
				return
			elseif status == TIE then
				EndRound(status)
				return
			elseif status == TWO then
				FinalRound()
			end
		end
	end
end

function StartWinChecks()
   if not timer.Start("wincheck") then
      timer.Create("wincheck", 1, 0, WinCheck)
   end
end

function StopWinChecks()
   timer.Stop("wincheck")
end

local function CleanUp()
	game.CleanUpMap(false, {"env_beam"})
	
	for k,v in pairs(player.GetAll()) do
		if IsValid(v) then
			v:StripWeapons()
		end
	end
end

function GraceRound()
	CleanUp()
	
	local gracetime = GetConVar("glms_gracetime"):GetInt()
	if GAMEMODE.FirstRound then
		gracetime = GetConVar("glms_initialgracetime"):GetInt()
		GAMEMODE.FirstRound = false
	end
	
	timer.Create("startround", gracetime, 1, StartRound)
	
	SetRound(ROUND_GRACE)
	game.ConsoleCommand("say Grace\n")
end

function StartRound()
	local roundtime = CurTime() + (GetConVar("glms_roundtime"):GetInt() * 60)
	
	SetGlobalFloat("glms_round_end", roundtime)
	StartWinChecks()
	SetRound(ROUND_START)
	game.ConsoleCommand("say Start\n")
end

function FinalRound()

end

function EndRound(type)
	if type == TIE then
		--No win
	elseif type == WIN then
		--"winner" (SteamID) won (this should probably be perfected)
	else
		--Unknown round end reason
	end
	
	SetRound(ROUND_END)
	
	local endtime = GetConVar("glms_endtime"):GetInt()
	timer.Create("graceround", endtime, 1, GraceRound)
	
	local roundend = CurTime() + endtime
	SetGlobalFloat("glms_round_end", roundend)
	
	StopWinChecks()
	game.ConsoleCommand("say End\n")
end

function RoundStateCmd(ply, cmd, args)
	MsgAll(GAMEMODE.round)
end
concommand.Add( "roundstate", RoundStateCmd )